#ifndef WALKAWARE_SHARED_DETAIL_RAWDEPTHMAPPRIVATE_H
#define WALKAWARE_SHARED_DETAIL_RAWDEPTHMAPPRIVATE_H

#include <assert.h>
#include <memory.h>

#include <QVector>
#include <QSharedData>

namespace WalkaWare
{

namespace Shared
{

namespace Detail
{

class RawDepthMapPrivate : public QSharedData
{
	public:

		typedef QSharedData        BaseType;
		typedef RawDepthMapPrivate ThisType;

		RawDepthMapPrivate(void)
			: dwidth   (0)
			, dheight  (0)
		{
			;
		}

		RawDepthMapPrivate(const ThisType & other)
			: BaseType (other)
			, dwidth   (other.dwidth)
			, dheight  (other.dheight)
			, dmap     (other.dmap)
		{
			;
		}

		RawDepthMapPrivate(int width, int height, const quint16 * data = 0)
			: dwidth   (0)
			, dheight  (0)
		{
			this->setup(width, height, data);
		}

		~RawDepthMapPrivate(void)
		{
			;
		}

		void setup(int width, int height, const quint16 * data = 0)
		{
			assert(width  >= 0);
			assert(height >= 0);
			if ((width == this->dwidth) &&  (height == this->dheight)) return;

			this->clear();
			if ((width <= 0) || (height <= 0)) return;

			this->dwidth  = width;
			this->dheight = height;
			this->dmap.resize(this->dwidth * this->dheight);

			if (data != 0)
			{
				memcpy(this->dmap.data(), data, this->dwidth * this->dheight * sizeof(quint16));
			}
		}

		void clear(void)
		{
			this->dwidth  = 0;
			this->dheight = 0;
			this->dmap.clear();
		}

		void fill(quint16 value = 0)
		{
			this->dmap.fill(value);
		}

		int width(void) const
		{
			return this->dwidth;
		}

		int height(void) const
		{
			return this->dheight;
		}

		int size(void) const
		{
			return this->dmap.size();
		}

		bool isEmpty(void) const
		{
			return this->dmap.empty();
		}

		const QVector<quint16> & data(void) const
		{
			return this->dmap;
		}

		QVector<quint16> & data(void)
		{
			return this->dmap;
		}

		int indexOf(int x, int y) const
		{
			return (x + y * this->dwidth);
		}

		quint16 at(int x, int y) const
		{
			const int index = this->indexOf(x, y);
			assert((index >= 0) && (index < this->size()));
			return this->dmap[index];
		}

		quint16 & at(int x, int y)
		{
			const int index = this->indexOf(x, y);
			assert((index >= 0) && (index < this->size()));
			return this->dmap[index];
		}

		quint16 operator () (int x, int y) const
		{
			return this->at(x, y);
		}

		quint16 & operator () (int x, int y)
		{
			return this->at(x, y);
		}

	protected:

		int              dwidth;
		int              dheight;
		QVector<quint16> dmap;
};

} // end namespace Detail

} // end namespace Shared

} // end namespace WalkaWare

#endif // WALKAWARE_SHARED_DETAIL_RAWDEPTHMAPPRIVATE_H
